<?php

namespace classes;

use think\Exception;
use think\facade\Cache;
use think\Db;


//【PHP】用Redis实现限流的常见方案 https://www.cnblogs.com/caiawo/p/14117534.html
//  https://gitee.com/fangaolin/limit_demo
//https://blog.csdn.net/fdipzone/article/details/79352685  (采用)


class TokenBucket
{
    const KEY = 'mycontainer';
    const MAX_TOKEN = 0; //令牌数后台配置

    /**
     * 加入令牌
     * @param  Int $num 加入的令牌数量
     * @return Int 加入的数量
     */
    public static function add($num = 0)
    {

        $config = RedisClass::get_vote_config_info();
        // 当前剩余令牌数
        $curnum = intval(Cache::store('redis')->handler()->LLEN(self::KEY));

        // 最大令牌数
        $maxnum = intval($config['total_limit_count']);

        // 计算最大可加入的令牌数量，不能超过最大令牌数
        $num = $maxnum >= $curnum + $num ? $num : $maxnum - $curnum;

        // 加入令牌
        if ($num > 0) {
            $token = array_fill(0, $num, 1);
            Cache::store('redis')->handler()->lPush(self::KEY, ...$token);
            return $num;
        }

        return 0;

    }

    /**
     * 获取令牌
     * @return Boolean
     */
    public static function get()
    {
        return Cache::store('redis')->handler()->rPop(self::KEY) ? true : false;
    }

    /**
     * 重设令牌桶，填满令牌
     */
    public static function reset()
    {
        Cache::store('redis')->handler()->del(self::KEY);
        $config = RedisClass::get_vote_config_info();
        self::add($config['total_limit_count']);
    }


}